package com.sensetime.jv.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sensetime.jv.entity.*;
import com.sensetime.jv.exception.CustomException;
import com.sensetime.jv.mapper.*;
import com.sensetime.jv.service.AuthService;
import com.sensetime.jv.service.CaptchaService;
import com.sensetime.jv.service.TokenCacheService;
import com.sensetime.jv.util.UserInfoUtils;
import com.sensetime.jv.vo.request.LoginReqVO;
import com.sensetime.jv.vo.response.LoginRespVO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
public class AuthServiceImpl implements AuthService {

    @Resource
    private UsersMapper usersMapper; // 用户表Mapper

    @Resource
    private UserRolesMapper userRolesMapper; // 用户-角色关联表Mapper


    @Resource
    private RolePermissionsMapper rolePermissionsMapper; // 角色-权限关联表Mapper
    @Resource
    private RolesMapper rolesMapper; // 角色-权限关联表Mapper

    @Resource
    private PermissionsMapper permissionsMapper; // 权限表Mapper

    @Resource
    private CaptchaService captchaService;

    private String bizType = "login";


    @Value("${custom.local.debug:true}")
    private boolean debug;

    @Override
    public LoginRespVO login(LoginReqVO loginReqVO) {
        // 校验用户登录信息
        UsersJv user = checkLoginInfo(loginReqVO);
        // 封装用户信息并生成Token
        LoginRespVO loginRespVO = getUserInfo(user.getId(), null);
        return loginRespVO;
    }

    /**
     * 校验用户登录信息
     * @param loginReqVO 登录请求对象
     * @return 返回用户基本信息
     */
    private UsersJv checkLoginInfo(LoginReqVO loginReqVO) {
        // 1. 验证验证码（暂时注释掉）
        if (!debug && !captchaService.validate(bizType, loginReqVO.getUsername(), loginReqVO.getCaptcha())) {
            throw new CustomException("验证码错误");
        }

        // 2. 查询用户基本信息
        UsersJv user = getUserByUsernameAndPassword(loginReqVO.getUsername(), loginReqVO.getPassword());
        if (user == null) {
            log.error("用户[{}]不存在", loginReqVO.getUsername());
            throw new CustomException("用户名或密码错误");
        }
        return user;
    }

    /**
     * 根据用户ID封装用户信息并生成Token
     *
     * @param userId 用户ID
     * @param token
     * @return 返回登录响应对象
     */
    @Override
    public LoginRespVO getUserInfo(Integer userId, String token) {
        // 查询用户关联的角色ID
        List<Integer> roleIds = getUserRoleIds(userId);

        // 查询角色关联的权限ID
        List<Integer> permissionIds = getPermissionIdsByRoleIds(roleIds);

        // 查询具体的权限名称
        List<PermissionsJv> permissionsJvs = getPermissionNames(permissionIds);

        // 查询角色信息
        List<RolesJv> rolesJvs = getRolesByRoleIds(roleIds);

        // 查询用户基本信息
        UsersJv user = usersMapper.selectById(userId);

        // 封装为LoginUser对象
        LoginUser loginUser = new LoginUser();
        loginUser.setUser(user);
        loginUser.setPermissions(permissionsJvs);
        loginUser.setRoles(rolesJvs);
        log.info("用户[{}]权限加载完成，权限列表: {}", user.getUsername(), permissionsJvs);
        // 获取当前请求
        // 生成Token
        token = TokenCacheService.getInstance().generateToken(user.getId().toString(),loginUser, token);

        // 返回登录响应
        LoginRespVO loginRespVO = new LoginRespVO();
        loginRespVO.setToken(token);
        loginRespVO.setUserName(user.getUsername());
        loginRespVO.setPermissions(permissionsJvs);
        loginRespVO.setRoles(rolesJvs);
        return loginRespVO;
    }

    // 提取用户信息
    private UsersJv getUserByUsernameAndPassword(String username, String password) {
        LambdaQueryWrapper<UsersJv> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(UsersJv::getUsername, username).eq(UsersJv::getPassword, password);
        return usersMapper.selectOne(userQuery);
    }

    // 提取用户角色ID
    private List<Integer> getUserRoleIds(Integer userId) {
        QueryWrapper<UserRolesJv> userRoleQuery = new QueryWrapper<>();
        userRoleQuery.eq("user_id", userId);
        return userRolesMapper.selectList(userRoleQuery).stream()
                .map(UserRolesJv::getRoleId)
                .collect(Collectors.toList());
    }

    // 提取角色权限ID
    private List<Integer> getPermissionIdsByRoleIds(List<Integer> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return Collections.emptyList();
        }
        QueryWrapper<RolePermissionsJv> rolePermQuery = new QueryWrapper<>();
        rolePermQuery.in("role_id", roleIds);
        return rolePermissionsMapper.selectList(rolePermQuery).stream()
                .map(RolePermissionsJv::getPermissionId)
                .collect(Collectors.toList());
    }

    // 提取权限名称
    private List<PermissionsJv> getPermissionNames(List<Integer> permissionIds) {
        if (CollectionUtils.isEmpty(permissionIds)) {
            return Collections.emptyList();
        }
        QueryWrapper<PermissionsJv> permQuery = new QueryWrapper<>();
        permQuery.in("id", permissionIds);
        return permissionsMapper.selectList(permQuery);
    }

    // 提取角色信息
    private List<RolesJv> getRolesByRoleIds(List<Integer> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return Collections.emptyList();
        }
        return rolesMapper.selectByIds(roleIds);
    }

    @Override
    public void logout() {
        LoginUser userInfo = UserInfoUtils.getUserInfo();
        TokenCacheService.getInstance().removeUseInfo(userInfo.getUser().getId());
    }


}
